<!-- ImageUploader.vue -->
<template>
  <div class="image-uploader">
    <p class="upload-label">{{ title }}</p>

    <el-upload
        class="upload-container"
        action="#"
        :auto-upload="false"
        :show-file-list="true"
        list-type="picture-card"
        :file-list="fileList"
        :on-change="handleChange"
        :on-remove="handleRemove"
        :limit="limit"
        multiple
        accept="image/*"
    >
      <template #default>
        <div class="upload-icon-container">
          <i class="el-icon-plus"></i>
          <span>添加图片</span>
        </div>
      </template>
    </el-upload>
  </div>
</template>

<script>
import { ref, reactive } from 'vue'
import axios from 'axios'

export default {
  name: 'ImageUploader',
  props: {
    // 标题文字
    title: {
      type: String,
      default: '添加照片'
    },
    // 上传接口
    uploadUrl: {
      type: String,
      default: '/api/upload'
    },
    // 图片数量限制
    limit: {
      type: Number,
      default: 9
    }
  },
  emits: ['update:uploadedImages'],
  setup(props, { emit }) {
    const fileList = ref([])
    const selectedFiles = ref([])
    const uploadedImageUrls = ref([])

    // 处理文件选择
    const handleChange = (file) => {
      // 将新选择的文件添加到待上传列表
      if (file.status === 'ready') {
        const fileObj = {
          raw: file.raw,
          url: URL.createObjectURL(file.raw),
          status: 'ready'
        }
        selectedFiles.value.push(fileObj)
      }
    }

    // 处理文件移除
    const handleRemove = (file) => {
      // 从待上传列表中移除
      const index = selectedFiles.value.findIndex(item =>
          item.url === file.url || item.raw === file.raw
      )

      if (index !== -1) {
        selectedFiles.value.splice(index, 1)
      }

      // 同时要检查是否已经在上传列表中，如果有也要移除
      const uploadIndex = uploadedImageUrls.value.findIndex(url =>
          url === file.url || url.includes(file.name)
      )

      if (uploadIndex !== -1) {
        uploadedImageUrls.value.splice(uploadIndex, 1)
        // 通知父组件
        emit('update:uploadedImages', uploadedImageUrls.value)
      }
    }

    // 上传所有待上传的文件
    const uploadAllFiles = async () => {
      const pendingFiles = selectedFiles.value.filter(file => file.status === 'ready')

      if (pendingFiles.length === 0) {
        return uploadedImageUrls.value // 如果没有待上传文件，直接返回当前已上传的URL列表
      }

      const uploadPromises = pendingFiles.map(async (file) => {
        try {
          const formData = new FormData()
          formData.append('file', file.raw)

          const response = await axios.post(props.uploadUrl, formData, {
            headers: { 'Content-Type': 'multipart/form-data' }
          })

          // 标记该文件为已上传
          file.status = 'success'

          // 添加到已上传列表
          uploadedImageUrls.value.push(response.data)

          return response.data
        } catch (error) {
          console.error('图片上传失败:', error)
          file.status = 'error'
          return null
        }
      })

      await Promise.all(uploadPromises)

      // 更新已上传的图片URLs到父组件
      emit('update:uploadedImages', uploadedImageUrls.value)

      return uploadedImageUrls.value
    }

    // 清空所有选择的文件
    const clearFiles = () => {
      fileList.value = []
      selectedFiles.value = []
      uploadedImageUrls.value = []
      emit('update:uploadedImages', [])
    }

    return {
      fileList,
      handleChange,
      handleRemove,
      uploadAllFiles,
      clearFiles,
      uploadedImageUrls
    }
  }
}
</script>

<style scoped>
.image-uploader {
  margin-bottom: 20px;
}

.upload-label {
  font-size: 15px;
  font-weight: 500;
  color: #374151;
  margin-bottom: 12px;
}

.upload-icon-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  color: #6b7280;
}

:deep(.el-upload--picture-card) {
  width: 80px;
  height: 80px;
  line-height: 80px;
  border-radius: 8px;
  border: 1px dashed #d9d9d9;
}

:deep(.el-upload--picture-card:hover) {
  border-color: #10b981;
}

:deep(.el-upload-list--picture-card .el-upload-list__item) {
  width: 80px;
  height: 80px;
  border-radius: 8px;
}
</style>